package cn.tedu.csmall.product.service.impl;

import cn.tedu.csmall.product.ex.ServiceException;
import cn.tedu.csmall.product.mapper.BrandCategoryMapper;
import cn.tedu.csmall.product.mapper.CategoryAttributeTemplateMapper;
import cn.tedu.csmall.product.mapper.CategoryMapper;
import cn.tedu.csmall.product.mapper.SpuMapper;
import cn.tedu.csmall.product.pojo.dto.CategoryAddNewDTO;
import cn.tedu.csmall.product.pojo.dto.CategoryUpdateDTO;
import cn.tedu.csmall.product.pojo.entity.Category;
import cn.tedu.csmall.product.pojo.vo.CategoryListItemVO;
import cn.tedu.csmall.product.pojo.vo.CategoryStandardVO;
import cn.tedu.csmall.product.service.ICategoryService;
import cn.tedu.csmall.product.web.ServiceCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Slf4j
@Service
public class CategoryServiceImpl implements ICategoryService {
    @Autowired
    CategoryMapper categoryMapper;
    @Autowired
    BrandCategoryMapper brandCategoryMapper;
    @Autowired
    SpuMapper spuMapper;
    @Autowired
    CategoryAttributeTemplateMapper categoryAttributeTemplateMapper;

    public CategoryServiceImpl(){
        log.debug("创建业务对象:CategoryServeImpl");
    }

    @Override
    @Transactional
    public void addNew(CategoryAddNewDTO categoryAddNewDTO) {
        log.debug("开始处理[添加分类业务],参数:{}",categoryAddNewDTO);
        //查询父级类别
        Integer depth = 1;
        Long parentId = categoryAddNewDTO.getParentId();
        CategoryStandardVO parentCategory = null;
        if (parentId != 0) {
            //确定当前类别的depth值,为:父级depth+1
            parentCategory = categoryMapper.getCategoryStandard(parentId);
            log.debug("根据父类级别ID[{}]查询父级类别详情, 结果:{}",parentId, parentCategory);
            if (parentCategory == null) {
                String message = "添加类别失败, 所选择的父级类别不存在!";
                log.debug(message);
//                throw new ServiceException(ServiceCode.NOT_FOUND_ERROR, message);
            }
            depth = parentCategory.getDepth() +1 ;
        }
        log.debug("当前尝试添加的类型的depth值为:{}", depth);

        //获得类别的名字
        String name = categoryAddNewDTO.getName();
        //判断名字是否被占用
        int i = categoryMapper.countByName(name);
        if (i>0) {
            //是: 名字被占用,添加分类失败
            String message = "名字被占用,添加分类失败";
            log.debug(message);
            throw new ServiceException(ServiceCode.ERR_CONFLICT, message);
        }
        //否: 名字未被占用,可以添加分类
        log.debug("名字未被占用,可以添加分类");
        Category category = new Category();
        BeanUtils.copyProperties(categoryAddNewDTO,category);
        category.setDepth(depth);
        category.setIsParent(0);
        log.debug("准备添加类别, 参数:{}",category);
        int rows = categoryMapper.insert(category);
        if (rows !=1) {
            String message = "添加失败,服务器忙,请稍后再试!";
            throw new ServiceException(ServiceCode.ERR_INSERT,message);
        }

        if (parentId != 0) {
            if (parentCategory.getIsParent() ==0) {
                Category updateParentCategory = new Category();
                updateParentCategory.setId(parentId);
                updateParentCategory.setIsParent(1);
                log.debug("将父级类别的isParent更新为1, 更新参数对象:{}",updateParentCategory);
                rows = categoryMapper.update(updateParentCategory);
                if (rows !=1) {
                    String message = "修改失败,服务器忙,请稍后再试!";
                    throw new ServiceException(ServiceCode.ERR_UPDATE, message);
                }
            }
        }
        log.debug("添加分类完成");
    }

    @Override
    @Transactional
    public void delete(Long id) {
        log.debug("开始处理删除类别列表业务, 参数:{}",id);
        //判断访问的数据是否存在
        CategoryStandardVO categoryStandard = categoryMapper.getCategoryStandard(id);
        if (categoryStandard == null) {
            //否: 尝试访问的数据不存在, 抛出异常, 删除失败
            String message = "尝试访问的数据不存在, 删除失败";
            log.debug(message);
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, message);
        }

        //是: 继续判断类别是否关联了品牌
        log.debug("继续判断类别是否关联了品牌");
        int i = brandCategoryMapper.countByCategoryId(id);
        if (i > 0) {
            //是: 有关联品牌, 不能删除, 抛出异常
            String message = "删除失败, 该类别存在关联的品牌";
            log.debug(message);
            throw new ServiceException(ServiceCode.ERR_CONFLICT, message);
        }
        //否: 继续判断是否关联了属性模板
        i = categoryAttributeTemplateMapper.countByCategoryId(id);
        if (i > 0) {
            //是: 存在关联, 抛出异常, 删除失败
            String message = "删除失败, 该类别存在关联的属性模板数据";
            log.debug(message);
            throw new ServiceException(ServiceCode.ERR_CONFLICT, message);
        }

        //否: 继续判断是否关联了SPU
        log.debug("继续判断是否关联了SPU");
        i = spuMapper.countByCategoyrId(id);
        if (i > 0) {
            //是: 存在关联, 抛出异常, 删除失败
            String message = "删除失败, 该类别存在关联的SPU数据";
            log.debug(message);
            throw new ServiceException(ServiceCode.ERR_CONFLICT, message);
        }

        //继续判断该类别是否是某个父类的最后一个子级类别
        Integer isParent = categoryStandard.getIsParent();
        Long parentId = categoryStandard.getParentId();
        log.debug("判断该类别是否是某个父类的最后一个子集类别");
        i = categoryMapper.countByParentId(parentId);
        log.debug("查询结果:{}",i);
        if (isParent == 0 && parentId != 0 && i == 1) {
            //是某个父类的最后一个子集类别, 则将isParent改为0
            log.debug("是某个父类的最后一个子集类别, 则将isParent改为0");
            CategoryUpdateDTO dto = new CategoryUpdateDTO();
            dto.setIsParent(0);
            dto.setId(parentId);
            categoryMapper.updateById(dto);
        }
        //准备删除类别
        log.debug("准备删除类别, 参数:{}",id);
        i = categoryMapper.deleteById(id);
        if (i != 1) {
            String message = "删除失败,服务器忙,请稍后再试!";
            throw new ServiceException(ServiceCode.ERR_UPDATE, message);
        }
    }

    @Override
    public List<CategoryListItemVO> list() {
        log.debug("开始处理查询类别列表业务");
        return categoryMapper.listCategory();
    }

    @Override
    public List<CategoryListItemVO> listByParentId(Long parentId) {
        log.debug("开始处理根据父类id查询类别列表业务");
        return categoryMapper.listByParentId(parentId);
    }

    @Override
    public void enAble(Long id) {
        setEnable(id, 1);
    }

    @Override
    public void unEnAble(Long id) {
        setEnable(id, 0);
    }

    @Override
    public void disPlay(Long id) {
        setDisplay(id, 1);
    }

    @Override
    public void unDisPlay(Long id) {
        setDisplay(id, 0);
    }

    @Override
    public CategoryStandardVO getStandardById(Long id) {
        log.debug("开始处理查询类别详情业务,参数:{}",id);
        CategoryStandardVO vo = categoryMapper.getCategoryStandard(id);
        if (vo == null) {
            String message = "品牌分类数据不存在,查询失败";
            log.debug(message);
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, message);
        }
        return vo;
    }

    @Override
    public void updateById(CategoryUpdateDTO categoryUpdateDTO) {
        log.debug("开始处理查询类别详情业务,参数:{}",categoryUpdateDTO);
        //判断id是否存在
        CategoryStandardVO categoryStandard = categoryMapper.getCategoryStandard(categoryUpdateDTO.getId());
        if (categoryStandard == null){
            //否: 不存在,抛出异常,修改失败
            String message = "品牌分类数据不存在,修改失败";
            log.debug(message);
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, message);
        }
        //是: 存在, 判断修改的名字是否有重复
        int i = categoryMapper.countByName(categoryUpdateDTO.getName());
        if (i > 0) {
            //是: 有重复, 抛出异常, 修改失败
            String message = "类别名称已被占用, 修改失败";
            log.debug(message);
            throw new ServiceException(ServiceCode.ERR_CONFLICT, message);
        }
        //否: 名称未被占用, 可以修改
        log.debug("名称未被占用, 可以修改, 参数:{}",categoryUpdateDTO);
        i = categoryMapper.updateById(categoryUpdateDTO);
        if (i != 1){
            String message = "修改失败, 服务器忙, 请稍后再试";
            log.debug(message);
            throw new ServiceException(ServiceCode.ERR_UPDATE, message);
        }

    }

    /**
     * 修改是否显示在导航栏
     * @param id
     * @param disPlay
     */
    private void setDisplay(Long id, Integer disPlay){
        String[] s = {"隐藏", "显示"};
        //判断id是否存在
        CategoryStandardVO vo = categoryMapper.getCategoryStandard(id);
        if (vo == null) {
            //否: 不存在,抛出异常,删除失败
            String message = "品牌分类数据不存在,"+s[disPlay]+"失败";
            log.debug(message);
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, message);
        }
        //是: 存在, 判断状态是否冲突
        if (vo.getIsDisplay() == disPlay) {
            //是: 状态冲突, 抛出异常
            String message = "状态冲突,"+s[disPlay]+"失败";
            log.debug(message);
            throw new ServiceException(ServiceCode.ERR_CONFLICT, message);
        }
        //否: 可以修改
        Category category = new Category();
        category.setId(id);
        category.setIsDisplay(disPlay);
        log.debug("准备修改, 参数:{}",category);
        categoryMapper.update(category);
        log.debug("修改完成");
    }


    /**
     * 修改是否启用
     * @param id
     * @param enable
     */
    private void setEnable(Long id, Integer enable){
        String[] s = {"未启用", "启用"};
        //判断id是否存在
        CategoryStandardVO vo = categoryMapper.getCategoryStandard(id);
        if (vo == null) {
            //否: 不存在,抛出异常,删除失败
            String message = "品牌分类数据不存在,修改状态为"+s[enable]+"失败";
            log.debug(message);
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, message);
        }
        //是: 存在, 判断状态是否冲突
        if (vo.getEnable() == enable) {
            //是: 状态冲突, 抛出异常
            String message = "状态冲突,修改状态为"+s[enable]+"失败";
            log.debug(message);
            throw new ServiceException(ServiceCode.ERR_CONFLICT, message);
        }
        //否: 可以修改
        Category category = new Category();
        category.setId(id);
        category.setEnable(enable);
        log.debug("准备修改, 参数:{}",category);
        categoryMapper.update(category);
        log.debug("修改完成");
    }
}
